package controller

import (
	"GoTime/models"
	"GoTime/response"
	"log"
	"net/http"
	"strconv"
	"strings"
	"time"

	. "GoTime/utils"
	"encoding/json"

	"github.com/gin-gonic/gin"
	"github.com/spf13/cast"
	"xorm.io/builder"
)

func GetSecurityList(c *gin.Context) {
	var (
		securityList []*response.SecurityListResponse // 用于存储场地列表的响应
		err          error                            // 用于存储可能发生的错误
		page         int                              // 当前页码
		pageSize     int                              // 每页显示的记录数
		offset       int                              // 数据库查询时的偏移量
		count        int64                            // 场地列表的总记录数
	)

	// 检查请求中是否包含驾校ID参数
	if c.Query("school_id") == "" {
		// 如果驾校ID参数为空，返回错误信息
		c.JSON(http.StatusBadRequest, gin.H{"code": 201, "msg": "请选择驾校"})
		return
	}

	// 获取当前页码，默认为0
	page = cast.ToInt(c.DefaultQuery("page", "0"))
	// 获取每页显示的记录数，默认为10
	pageSize = cast.ToInt(c.DefaultQuery("pageSize", "10"))
	// 计算数据库查询的偏移量
	offset = (page - 1) * pageSize

	// 创建一个新的查询条件构建器
	filter := builder.NewCond()
	// 添加驾校ID的查询条件
	filter = filter.And(builder.Eq{"c.school_id": c.Query("school_id")})

	// 如果请求中包含名称参数，则添加
	if username := c.Query("name"); username != "" {
		filter = filter.And(builder.Like{"u.name", username})
	}
	if phone := c.Query("phone"); phone != "" {
		filter = filter.And(builder.Like{"u.phone", phone})
	}
	if status := c.Query("status"); status != "" {
		filter = filter.And(builder.Eq{"c.status": status})
	}

	securityList, count, err = new(models.Securityguard).GetSecurityList(filter, pageSize, offset)

	// 如果发生错误，返回错误信息
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "获取安全员列表失败", "data": err})
		return
	}

	// 如果成功，返回成功信息及数据
	c.JSON(http.StatusOK, gin.H{"code": 200, "msg": "获取安全员列表成功", "data": gin.H{"count": count, "list": securityList}})
	return
}

func AddSecurity(c *gin.Context) {
	var (
		err error
	)
	security := new(models.Securityguard)
	user := new(models.User)
	portrait := new(models.Portrait)
	// 解析请求参数
	if err = c.ShouldBind(&security); err != nil {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "参数解析失败", "data": err.Error()})
		return
	}
	if err = c.ShouldBind(&user); err != nil {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "参数解析失败", "data": err.Error()})
		return
	}
	if err = c.ShouldBind(&portrait); err != nil {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "参数解析失败", "data": err.Error()})
		return
	}
	ok, school, err := new(models.School).GetSchoolById(cast.ToInt(c.PostForm("school_id")))
	if err != nil || !ok {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "驾校不存在"})
		return
	}
	if security.DrivingCarType != "" && security.TeachingCarType != "" {
		if DrivingCarTypeMap[security.DrivingCarType] <= DrivingCarTypeMap[security.TeachingCarType] {

		} else {
			c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "准驾车型与准教车型不匹配"})
			return
		}
	}
	if c.PostForm("licence_grant_date") == "" {
	} else {
		if security.LicenceGrantDate, err = time.Parse("2006-01-02", c.PostForm("licence_grant_date")); err != nil {
			log.Println(err.Error())
			c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "驾驶证初领日期格式错误"})
			return
		}
	}

	if c.PostForm("entry_date") == "" {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "入职日期不能为空"})
		return
	} else {
		if security.EntryDate, err = time.Parse("2006-01-02", c.PostForm("entry_date")); err != nil {
			c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "入职日期格式错误"})
			return
		}
	}
	if c.PostForm("portrait_code") == "" {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "头像未上传或上传失败"})
		return
	}
	user.Password = Md5(user.IdNumber[len(user.IdNumber)-6:]) // 对密码进行加密
	user.Phone = user.Phone + "s"
	user.IdNumber = user.IdNumber + "s"
	user.Isused = "1"
	user.Type = "6"
	user.IdType = "1"
	if err = user.CheckData(1); err != nil {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": err.Error()})
		return
	}

	// 获取数据库引擎实例
	var engine = models.Engine
	// 创建一个新的数据库会话
	var session = engine.NewSession()
	// 确保在函数结束时关闭会话
	defer session.Close()

	// 开始一个数据库事务
	if err := session.Begin(); err != nil {
		// 如果事务开始失败，返回错误信息
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "事务开始失败"})
		return
	}

	if _, err := session.Insert(user); err != nil {
		session.Rollback()
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": err.Error()})
		return
	}
	portrait.UserId = user.Id
	portrait.AddTime = time.Now()
	if _, err := session.Insert(portrait); err != nil {
		session.Rollback()
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": err.Error()})
		return
	}
	//请求百度人脸识别接口
	log.Println("百度人脸识别接口：", user.Phone, user.IdNumber)
	if err = BaiduCheck(portrait.ImageUrl, user.Phone, user.IdNumber, school.Province); err != nil {
		session.Rollback()
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": err.Error()})
		return
	}
	security.PortraitId = portrait.Id
	security.UserId = user.Id
	security.SchoolId = school.Id
	security.RecordStatus = "0"
	security.ApprovalStatus = "0"
	security.Isused = "1"
	security.InstitutionCode = GetInstitutionCode(strings.TrimRight(user.IdNumber, "s"))
	if _, err = session.Insert(security); err != nil {
		session.Rollback()
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": err.Error()})
		return
	}
	if err = security.RecordSecurity(school.InstitutionCode, user, portrait.InstitutionCode, "", school.Province, school.City, portrait.ImageUrl); err != nil {
		session.Rollback()
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": err.Error()})
		return
	}
	_, err = session.Exec("update dts_securityguard set record_status=? where id=?", "1", security.Id)
	if err != nil {
		session.Rollback()
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": err.Error()})
		return
	}
	err = session.Commit()
	if err != nil {
		session.Rollback()
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"code": 200, "msg": "添加成功"})
	return
}

func EditSecurity(c *gin.Context) {
	var (
		err error
	)
	security := new(models.Securityguard)
	user := new(models.User)
	portrait := new(models.Portrait)
	// 解析请求参数
	if err = c.ShouldBind(&security); err != nil {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "参数解析失败", "data": err.Error()})
		return
	}
	if err = c.ShouldBind(&user); err != nil {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "参数解析失败", "data": err.Error()})
		return
	}
	if err = c.ShouldBind(&portrait); err != nil {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "参数解析失败", "data": err.Error()})
		return
	}
	ok, school, err := new(models.School).GetSchoolById(cast.ToInt(c.PostForm("school_id")))
	if err != nil || !ok {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "驾校不存在"})
		return
	}
	if security.DrivingCarType != "" && security.TeachingCarType != "" {
		if DrivingCarTypeMap[security.DrivingCarType] <= DrivingCarTypeMap[security.TeachingCarType] {

		} else {
			c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "准驾车型与准教车型不匹配"})
			return
		}
	}
	if c.PostForm("licence_grant_date") == "" {
	} else {
		if security.LicenceGrantDate, err = time.Parse("2006-01-02", c.PostForm("licence_grant_date")); err != nil {
			log.Println(err.Error())
			c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "驾驶证初领日期格式错误"})
			return
		}
	}

	if c.PostForm("entry_date") == "" {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "入职日期不能为空"})
		return
	} else {
		if security.EntryDate, err = time.Parse("2006-01-02", c.PostForm("entry_date")); err != nil {
			c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "入职日期格式错误"})
			return
		}
	}
	if c.PostForm("portrait_code") == "" {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "头像未上传或上传失败"})
		return
	}
	if err = user.CheckData(1); err != nil {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": err.Error()})
		return
	}
	security, err = new(models.Securityguard).GetById(c.PostForm("security_id"))
	if err != nil || security.Id == 0 {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "安全员不存在"})
		return
	}

	user.Phone = user.Phone + "s"

	// 获取数据库引擎实例
	var engine = models.Engine
	// 创建一个新的数据库会话
	var session = engine.NewSession()
	// 确保在函数结束时关闭会话
	defer session.Close()

	// 开始一个数据库事务
	if err := session.Begin(); err != nil {
		// 如果事务开始失败，返回错误信息
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "事务开始失败"})
		return
	}
	if _, err := session.ID(security.PortraitId).Update(portrait); err != nil {
		session.Rollback()
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": err.Error()})
		return
	}
	if _, err := session.ID(security.UserId).Update(user); err != nil {
		session.Rollback()
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": err.Error()})
		return
	}
	//请求百度人脸识别接口
	log.Println("百度人脸识别接口：", user.Phone, user.IdNumber)
	if err = BaiduCheck(portrait.ImageUrl, user.Phone, user.IdNumber, school.Province); err != nil {
		session.Rollback()
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": err.Error()})
		return
	}
	security.PortraitId = portrait.Id
	security.RecordStatus = "0"
	security.ApprovalStatus = "0"
	if security.InstitutionCode == "" {
		security.InstitutionCode = GetInstitutionCode(strings.TrimRight(user.IdNumber, "s"))
	}
	if _, err = session.ID(security.Id).Update(security); err != nil {
		session.Rollback()
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": err.Error()})
		return
	}
	if err = security.RecordSecurity(school.InstitutionCode, user, portrait.InstitutionCode, "", school.Province, school.City, portrait.ImageUrl); err != nil {
		session.Rollback()
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": err.Error()})
		return
	}
	_, err = session.Exec("update dts_securityguard set record_status=? where id=?", "1", security.Id)
	if err != nil {
		session.Rollback()
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": err.Error()})
		return
	}
	err = session.Commit()
	if err != nil {
		session.Rollback()
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"code": 200, "msg": "修改成功"})
	return
}

func DeleteSecurity(c *gin.Context) {
	var (
		err        error
		securityId string
		schoolId   string
		url        string
		retMap     map[string]interface{}
	)
	// 获取请求中的场地ID参数
	if securityId = c.Query("security_id"); securityId == "" {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "缺少安全员ID"})
		return
	}

	// 获取请求中的驾校ID参数
	if schoolId = c.Query("school_id"); schoolId == "" {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "缺少驾校ID"})
		return
	}

	// 查询指定驾校ID的驾校信息
	ok, school, err := new(models.School).GetSchoolById(cast.ToInt(schoolId))
	if err != nil || !ok {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "查询驾校信息失败"})
		return
	}
	// 获取数据库引擎实例
	var engine = models.Engine
	// 创建一个新的数据库会话
	var session = engine.NewSession()
	// 确保在函数结束时关闭会话
	defer session.Close()

	// 开始一个数据库事务
	if err := session.Begin(); err != nil {
		// 如果事务开始失败，返回错误信息
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "事务开始失败"})
		return
	}

	// 创建一个新的Field模型实例
	security := new(models.Securityguard)

	// 通过ID查询场地信息
	if ok, err := session.ID(securityId).Where("school_id =?", school.Id).Get(security); err != nil || !ok {
		session.Rollback()
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "查询安全员信息失败"})
		return
	}

	// 构造请求URL
	if url, err = GetSignURL("securityguard-"+security.InstitutionCode, nil, 2, school.Province, school.City); err != nil {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": err.Error()})
		return
	}

	// 根据驾校所在省份设置API请求方法
	apiMethod := "DELETE"
	shanDong := school.Province == "370000"
	if shanDong {
		apiMethod = "GET"
	}

	// 创建一个新的ApiLog结构体实例，记录API请求信息
	var api_log models.ApiLog
	api_log.Url = url
	api_log.Param = ""
	api_log.Method = apiMethod
	api_log.UserId, _ = strconv.Atoi(c.PostForm("user_id"))
	api_log.Time = time.Now()

	// 发送API请求并获取返回结果
	if retMap, err = APIReq(url, nil, apiMethod); err != nil {
		result, _ := json.Marshal(retMap)
		api_log.Result = string(result)
		api_log.Add()
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "请求失败", "data": err.Error()})
		return
	}

	result, _ := json.Marshal(retMap)
	api_log.Result = string(result)
	api_log.Add()

	// 获取返回结果中的错误码
	errorcode, _ := cast.ToIntE(retMap["errorcode"])
	if errorcode != 0 {
		// 如果错误码不为0且消息中不包含“不存在”，则返回删除失败信息
		if strings.Contains(cast.ToString(retMap["message"]), "不存在") || strings.Contains(cast.ToString(retMap["message"]), "您尚未备案该安全员") {

		} else {
			c.JSON(http.StatusOK, gin.H{"code": 201, "msg": cast.ToString(retMap["message"]) + "1"})
			return
		}
	}
	//设为已删除及离职状态
	security.Isused = "0"
	security.Remark = security.InstitutionCode
	security.InstitutionCode = ""
	security.Status = "0"

	// 根据场地ID更新场地信息，如果更新失败，回滚事务并返回错误信息
	if _, err := session.ID(securityId).Cols("isused", "remark", "institution_code", "status").Update(security); err != nil {
		session.Rollback()
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "删除安全员失败", "data": err.Error()})
		return
	}
	var user models.User
	if _, err := session.ID(security.UserId).Get(&user); err != nil {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "删除安全员失败", "data": err.Error()})
		return
	}
	user.Isused = "0"
	user.Remark = user.Phone
	user.Phone = cast.ToString(time.Now().Unix())
	user.ReidNumber = user.IdNumber
	user.IdNumber = ""
	if _, err := session.ID(security.UserId).Cols("isused", "remark", "phone", "reid_number", "id_number").Update(user); err != nil {
		log.Println(err)
		session.Rollback()
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "删除安全员失败", "data": err.Error()})
		return
	}

	session.Commit()
	c.JSON(http.StatusOK, gin.H{"code": 200, "msg": "删除成功"})
	return
}
